#! /usr/bin/python
# Copyright (C) 2010  Johan Jordaan (www.johanjordaan.co.za)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Todo List:
# 
# 1) Better error handling.
# 2) Add Stats to the top of the file. Things like # of cards, etc etc
# 3) Add extra information to top of file like release date, block etc

import sys
sys.path.append('..\pylibs')
sys.path.append('..\pycommon')
import os
import os.path
from optparse import OptionParser   

import unicodecsv
import costparser
import filemappings as FM
from constants import *

cardtypes = ['artifact','creature','enchantment','instant','land','planeswalker','sorcery','tribal']
cardsupertypes  = ['tribal','basic','legendary','world','snow']
rarities = ['Common','Uncommon','Rare','Mythic Rare','Land']

def enrich_cost(card_dict):
    t = costparser.Cost(card_dict[COST]).hascost_cmc_color_isgold()
    card_dict[HASCOST] = '1' if t[0] else '0'
    card_dict[CMC] = str(t[1])
    card_dict[COLOR] = t[2]
    card_dict[ISGOLD] = '1' if t[3] else '0'

def enrich_type(card_dict):
  t = card_dict[TYPE].split('-')
  
  subtypes = []
  if len(t)>1:
    subtypes = t[1].strip().split(' ')

  types = []
  supertypes = []
  t[0] = t[0].replace('Basic Land','Basic-Land')
  for type in [x.strip() for x in t[0].strip().split(' ')]:
    isSupertype = False
    for supertype in cardsupertypes:
      if type == supertype:
        supertypes.append(type)
        isSupertype = True

    if not isSupertype:        
      types.append(type.replace('Basic-Land','Basic Land'))
  
  card_dict[TYPES] = ','.join(types)
  card_dict[SUBTYPES] = ','.join(subtypes)
  card_dict[SUPERTYPES] = ','.join(supertypes)

def enrich_power_toughness(card_dict):
  card_dict[HASVP] = '0'
  card_dict[HASVT] = '0'
  card_dict[HASPANDT] = '1'

  if len(card_dict[FM.PT].replace('(','').replace(')','').strip())==0:
    card_dict[P] = ''
    card_dict[T] = ''
    card_dict[HASPANDT] = '0'
  else:
    t = card_dict[FM.PT].replace('(','').replace(')','').split('/')
  
    card_dict[P] = t[0]
    card_dict[T] = t[1]
  
    if card_dict[FM.P] == '*':
      card_dict[FM.HASVP] = '1'

    if card_dict[T] == '*':
      card_dict[HASVT] = '1'

    if card_dict[P] == '' or card_dict[T] == '':
      card_dict[HASPANDT] = '0'
      
def enrich_loyalty(card_dict):
  card_dict[LOYALTY] = card_dict[LOYALTY].replace('(','').replace(')','').strip()    

def enrich_rarity(card_dict,set_name):
  sets_and_rarities = [set.strip() for set in card_dict[SET_RARITY].split(',')]

  for rarity in rarities:
    card_dict[FM.ECSV.key_for(rarity)] = ''
  
  rarity_by_set = {}
  for set_and_rarity in sets_and_rarities:
    rarities.sort(cmp=lambda a,b:cmp(len(a),len(b)),reverse=True)
    for rarity in rarities:
      if set_and_rarity.strip().lower().endswith(rarity.lower()):
        set = set_and_rarity.strip()[:-len(rarity)].strip()
        card_dict[FM.ECSV.key_for(rarity)] = set if card_dict[FM.ECSV.key_for(rarity)] == '' else card_dict[FM.ECSV.key_for(rarity)] + ',' + set  
        
        if set.strip().lower() == set_name.strip().lower():
          card_dict[RARITY] = rarity

        break
        
def parse_csv(file_name):
  f = open(file_name)
  r = unicodecsv.UnicodeReader(f)

  cards = []
  i = 0
  for row in r:
    if i == 0:              # The set name
      set_name = row[0]
    elif i == 1:            # The headers/keys
      keys = row
    else:                   # Everything else is data
      card_dict = {}
      for c in range(len(row)):
        # Read each item and assign them to the relevant indepenedt keys
        #
        card_dict[FM.CSV.key_for(keys[c])] = row[c]
      
      # Now enrich the data before adding it to the list    
      #
      enrich_cost(card_dict)
      enrich_type(card_dict)
      enrich_power_toughness(card_dict)
      enrich_loyalty(card_dict)
      enrich_rarity(card_dict,set_name)
      
      cards.append(card_dict)  
    i = i + 1  
  
  f.close()
  return set_name,cards  

def enrich_csv(file_name,input_root,output_root):
  print 'Enriching [%s] ...'%(file_name)
  
  # Read the source CSV
  #
  set_name,cards = parse_csv(os.path.join(os.path.join(input_root,'csv'),file_name))
  
  # Check that the destination directory exists, if it does not then create it
  #  
  if not os.path.exists(os.path.join(output_root,'csv')):
    os.mkdir(os.path.join(output_root,'csv'))


  f = open(os.path.join(os.path.join(output_root,'csv'),file_name),'wt')
  writer = unicodecsv.UnicodeWriter(f,lineterminator='\n')
  writer.writerow([set_name])
  writer.writerow(FM.ECSV.values())
  for card in cards:
    row_data = []
    for heading in FM.ECSV.keys():
      if heading in card.keys():
        row_data.append(card[heading].strip())
      else:
        row_data.append('')
    writer.writerow(row_data)
  f.close()

def enrich(input_root,output_root):  
  input_list = os.listdir(os.path.join(input_root,'csv'))
  
  for file_name in input_list:
    if file_name.endswith('.csv'):
      enrich_csv(file_name,input_root,output_root)
  
if __name__ == '__main__':
  parser = OptionParser()
  parser.add_option('-i', '--input',dest='input_root',default='..\data\gatherer',help='Root directory for the input data files')
  parser.add_option('-o', '--output',dest='output_root',default='..\data\enriched',help='Root directory for the output data files')
  
  (options, args) = parser.parse_args()
  
  enrich(options.input_root,options.output_root)
    


